import 'cool_ui.dart';
import 'package:flutter/material.dart';

class SafeKeyboardDemo extends StatefulWidget {
  final KeyboardController? controller;
  final ValueChanged<String>? onChanged;
  SafeKeyboardDemo({Key? key, this.controller, this.onChanged}) : super(key: key);
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return SafeKeyboard(controller: controller, onChanged: onChanged);
  }
}

double divide = 8;

class SafeKeyboard extends State<SafeKeyboardDemo> {
  static const CKTextInputType inputType = const CKTextInputType(name: 'CKTestKeyboard');
  static double getHeight(BuildContext? ctx) {
    if(ctx == null) {
      return 0;
    }
    MediaQueryData mediaQuery = MediaQuery.of(ctx);
    final size = mediaQuery.size;
    if(size.width > size.height) {
      h = 30 + divide;
      w = ((size.width + divide) / 10);
      return h * 5;
    }
    w = ((size.width + divide) / 10);
    h = w * 1.2;
    return h * 5;
  }

  final KeyboardController? controller;
  SafeKeyboard({this.controller, this.onChanged});
  bool isCaps = false;
  int type = 0;
  static double w = 0;
  static double h = 0;
  bool showKey = false;
  final ValueChanged<String>? onChanged;
  OverlayEntry? overlayEntry;
  String? currentChar = '';
  double left = 0;
  double top = 0;

  static register({ValueChanged<String>? onChanged}) {
    CoolKeyboard.addKeyboard(
        SafeKeyboard.inputType,
        KeyboardConfig(
            builder: (context, controller, params) {
              controller?.isPassword = true;
              controller?.passwordChar = '*';
              return SafeKeyboardDemo(controller: controller, onChanged: (val){
                CoolKeyboard.text = val;
                onChanged?.call(val);
              });
            },
            getHeight: SafeKeyboard.getHeight));
  }

  @override
  Widget build(BuildContext context) {
    MediaQueryData mediaQuery = MediaQuery.of(context);
    return Material(
      child: Overlay(
      initialEntries: [
        OverlayEntry(builder: (ctx) {
          return DefaultTextStyle(
          style: TextStyle(fontWeight: FontWeight.w500, color: Colors.black, fontSize: 23.0),
          child: Container(
              height: getHeight(context),
              width: mediaQuery.size.width,
              decoration: BoxDecoration(
                color: Color(0xFFE2E2E2),
              ),
              child: Column(
                children: [
                  Row(
                    children: [
                      Visibility(
                          visible: type != 1,
                          child: InkWell(
                            child: Container(height: h, width: w * 1.5, alignment: Alignment.center, child: Text('符', style: TextStyle(color: Colors.blue))),
                            onTap: () {
                              setState(() {
                                type = 1;
                              });
                            },
                          )),
                      Visibility(
                          visible: type != 2,
                          child: InkWell(
                            child: Container(height: h, width: w * 1.5, alignment: Alignment.center, child: Text('123', style: TextStyle(color: Colors.blue))),
                            onTap: () {
                              setState(() {
                                type = 2;
                              });
                            },
                          )),
                      Visibility(
                          visible: type != 0,
                          child: InkWell(
                            child: Container(height: h, width: w * 1.5, alignment: Alignment.center, child: Text('Abc', style: TextStyle(color: Colors.blue))),
                            onTap: () {
                              setState(() {
                                type = 0;
                              });
                            },
                          )),
                      InkWell(
                        child: Container(
                            height: h,
                            width: w * 1.5,
                            alignment: Alignment.center,
                            child: Icon(
                              showKey ? Icons.visibility : Icons.visibility_off,
                              color: showKey ? Colors.blue : Colors.grey,
                            )),
                        onTap: () {
                          setState(() {
                            showKey = !showKey;
                          });
                        },
                      ),
                      Expanded(
                        child: Container(
                          child: Text(
                            '安全键盘',
                            style: TextStyle(color: Colors.grey),
                          ),
                          alignment: Alignment.center,
                        ),
                      ),
                      InkWell(
                        child: Container(height: h, width: w + 10, alignment: Alignment.center, child: Text('完成', style: TextStyle(color: Colors.blue))),
                        onTap: () {
                          controller!.doneAction();
                        },
                      )
                    ],
                  ),
                  SizedBox(
                    height: divide / 2,
                  ),
                  type == 0
                      ? Column(
                    children: [
                      Row(
                        children: (List.generate(9, (index) => '${index + 1}')..add('0')).map((e) => buildButton(e)).toList(),
                        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      ),
                      SizedBox(
                        height: divide,
                      ),
                      Row(
                        children: ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'].map((e) => buildButton(e)).toList(),
                        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      ),
                      SizedBox(
                        height: divide,
                      ),
                      Row(
                        children: ['caps', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l']
                            .map((e) => e == 'caps'
                            ? Container(
                          decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(5)), color: Colors.white),
                          child: GestureDetector(
                            behavior: HitTestBehavior.translucent,
                            child: Container(
                              width: w - divide,
                              height: h - divide,
                              child: Icon(
                                Icons.keyboard_capslock,
                                color: isCaps ? Colors.blue : Colors.black,
                              ),
                              alignment: Alignment.center,
                            ),
                            onTap: () {
                              setState(() {
                                isCaps = !isCaps;
                              });
                            },
                          ),
                        )
                            : buildButton(e))
                            .toList(),
                        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      ),
                      SizedBox(
                        height: divide,
                      ),
                      Row(
                        children: ['space', 'z', 'x', 'c', 'v', 'b', 'n', 'm', 'delete'].map((e) {
                          if (e == 'space') {
                            return Container(
                              decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(5)), color: Colors.white),
                              child: GestureDetector(
                                behavior: HitTestBehavior.translucent,
                                child: Container(
                                  width: w - divide + w / 2,
                                  height: h - divide,
                                  child: Icon(Icons.space_bar),
                                  alignment: Alignment.center,
                                ),
                                onTap: () {
                                  controller!.addText(' ');
                                  onChanged?.call(controller!.realText);
                                },
                              ),
                            );
                          } else if (e == 'delete') {
                            return Container(
                              decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(5)), color: Colors.white),
                              child: GestureDetector(
                                behavior: HitTestBehavior.translucent,
                                child: Container(
                                  width: w - divide + w / 2,
                                  height: h - divide,
                                  child: Icon(Icons.backspace),
                                  alignment: Alignment.center,
                                ),
                                onTap: () {
                                  controller!.deleteOne();
                                  onChanged?.call(controller!.realText);
                                },
                              ),
                            );
                          } else {
                            return buildButton(e);
                          }
                        }).toList(),
                        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      )
                    ],
                  )
                      : type == 1
                      ? Column(children: [
                    Row(
                      children: ['!', '@', '#', '\$', '%', '^', '&', '*', '(', ')'].map((e) => buildButton(e)).toList(),
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    ),
                    SizedBox(
                      height: divide,
                    ),
                    Row(
                      children: ['-', '_', '=', '+', '`', '~', '[', ']', '{', '}'].map((e) => buildButton(e)).toList(),
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    ),
                    SizedBox(
                      height: divide,
                    ),
                    Row(
                      children: ['\\','|',';', ':', '\'', '"', ',', '<', '.', '>'].map((e) => buildButton(e)).toList(),
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    ),
                    SizedBox(
                      height: divide,
                    ),
                    Row(
                      children: ['/', '?','￥','€','￡', 'space', 'delete'].map((e) {
                        if (e == 'space') {
                          return Container(
                            decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(5)), color: Colors.white),
                            child: GestureDetector(
                              behavior: HitTestBehavior.translucent,
                              child: Container(
                                width: w - divide + w * 2.5,
                                height: h - divide,
                                child: Icon(Icons.space_bar),
                                alignment: Alignment.center,
                              ),
                              onTap: () {
                                controller!.addText(' ');
                                onChanged?.call(controller!.realText);
                              },
                            ),
                          );
                        } else if (e == 'delete') {
                          return Container(
                            decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(5)), color: Colors.white),
                            child: GestureDetector(
                              behavior: HitTestBehavior.translucent,
                              child: Container(
                                width: w - divide + w / 2,
                                height: h - divide,
                                child: Icon(Icons.backspace),
                                alignment: Alignment.center,
                              ),
                              onTap: () {
                                controller!.deleteOne();
                                onChanged?.call(controller!.realText);
                              },
                            ),
                          );
                        } else {
                          return buildButton(e);
                        }
                      }).toList(),
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    )
                  ])
                      : Column(children: [
                    Row(
                      children:
                      ['1', '2', '3'].map((e) => buildButton(e, customWidth: (MediaQuery.of(context).size.width - divide * 2) / 3)).toList(),
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    ),
                    SizedBox(
                      height: divide,
                    ),
                    Row(
                      children:
                      ['4', '5', '6'].map((e) => buildButton(e, customWidth: (MediaQuery.of(context).size.width - divide * 2) / 3)).toList(),
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    ),
                    SizedBox(
                      height: divide,
                    ),
                    Row(
                      children:
                      ['7', '8', '9'].map((e) => buildButton(e, customWidth: (MediaQuery.of(context).size.width - divide * 2) / 3)).toList(),
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    ),
                    SizedBox(
                      height: divide,
                    ),
                    Row(
                      children: ['.', '0'].map((e) => buildButton(e, customWidth: (MediaQuery.of(context).size.width - divide * 2) / 3)).toList()
                        ..add(Container(
                          decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(5)), color: Colors.white),
                          child: GestureDetector(
                            behavior: HitTestBehavior.translucent,
                            child: Container(
                              width: (MediaQuery.of(context).size.width - divide * 2) / 3,
                              height: h - divide,
                              child: Icon(Icons.backspace),
                              alignment: Alignment.center,
                            ),
                            onTap: () {
                              controller!.deleteOne();
                              onChanged?.call(controller!.realText);
                            },
                          ),
                        )),
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    )
                  ])
                ],
              )));}),
              OverlayEntry(
          builder: (ctx) {
            return left == 0 && top == 0
                ? Container()
                : Positioned(
                    left: left,
                    top: top,
                    child: Material(
                      child: Container(
                        width: (w - divide) * 1.2,
                        height: h,
                        alignment: Alignment.center,
                        padding: EdgeInsets.all(5),
                        child: Text(
                          currentChar!,
                          style: TextStyle(color: Colors.white, fontSize: 30, fontWeight: FontWeight.bold),
                        ),
                        color: Colors.black54,
                      ),
                    ),
                  );
          },
        )]),
    );
  }

  Widget buildButton(String title, {String? value, double offsetWidth = 0.0, double? customWidth}) {
    GlobalKey anchorKey = GlobalKey();
    if (isCaps) {
      title = title.toUpperCase();
    } else {
      title = title.toLowerCase();
    }
    if (value == null) {
      value = title;
    }
    return Container(
      key: anchorKey,
      decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(5)), color: Colors.white),
      child: Listener(
        behavior: HitTestBehavior.translucent,
        child: Container(
          width: customWidth == null ? w - divide + offsetWidth : customWidth,
          height: h - divide,
          child: Text(title),
          alignment: Alignment.center,
        ),
        onPointerDown: (e) {
          if (showKey) {
            RenderBox renderBox = anchorKey.currentContext!.findRenderObject() as RenderBox;
            var offset = renderBox.localToGlobal(Offset.zero);
            setState(() {
              currentChar = value;
              left = offset.dx - w * 0.1;
              top = offset.dy - h * 1.2 - (MediaQuery.of(anchorKey.currentContext!).size.height - getHeight(anchorKey.currentContext!));
            });
          }
          controller!.addText(value!);
          onChanged?.call(controller!.realText);
        },
        onPointerUp: (e) {
          if (showKey) {
            setState(() {
              left = 0;
              top = 0;
            });
          }
        },
      ),
    );
  }
}
